package com.ayun.controller;

import com.ayun.bean.Account;
import com.ayun.exception.InvalidArgument;
import com.ayun.exception.NoSuchAccountException;
import com.ayun.service.AccountService;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping("/account")
@Controller
public class AccountController {
    @Autowired
    private AccountService accountService;

    @RequestMapping("/login")
    public ModelAndView login(@Valid Account account, BindingResult result) throws NoSuchAccountException, InvalidArgument {
        System.out.println("login: "+account);
        account.setPassword(DigestUtils.md5Hex(account.getPassword()));

        if(result.hasErrors()) {
            throw new InvalidArgument(result.getFieldErrors());
        }

        if(!accountService.existAccount(account)) {
            throw new NoSuchAccountException("No such account!");
        }

        String target = "success";

        if("user".equals(account.getStatus())) {
            target = "redirect:../userInfo.html";
        }

        ModelAndView modelAndView = new ModelAndView(target);
        modelAndView.addObject("username",account.getUsername());

        return modelAndView;
    }

    @ResponseBody
    @RequestMapping("/checkUsername")
    public boolean checkUsername(@RequestBody String username) {
        return accountService.existUsername(username);
    }

    @RequestMapping("/logon")
    public ModelAndView logon(@Valid Account account, BindingResult result) throws InvalidArgument {
        System.out.println("logon: "+account);
        account.setPassword(DigestUtils.md5Hex(account.getPassword()));

        if(result.hasErrors()) {
            throw new InvalidArgument(result.getFieldErrors());
        }

        if(!"user".equals(account.getStatus())) {
            throw new RuntimeException("invalid status!");
        }

        accountService.logon(account);

        ModelAndView modelAndView = new ModelAndView("success");

        return modelAndView;
    }

    @ResponseBody
    @RequestMapping("/update")
    public boolean update(String username,String oldPassword,String newPassword,String status) {
        if(oldPassword == null || newPassword == null || oldPassword.equals(newPassword)) {
            return false;
        }
        oldPassword = DigestUtils.md5Hex(oldPassword);
        newPassword = DigestUtils.md5Hex(newPassword);

        Account account = new Account(username,oldPassword,status);

        if(!accountService.existAccount(account)) {
            return false;
        }

        account.setPassword(newPassword);
        accountService.updateAccount(account);
        return true;
    }

    @ExceptionHandler(InvalidArgument.class)
    public ModelAndView invalidArgument(InvalidArgument e) {
        List<FieldError> errors = e.getErrors();
        Map<String,Object> errorsMap = new HashMap<>();

        for(FieldError error : errors) {
            errorsMap.put(error.getField(), error.getDefaultMessage());
        }
        System.out.println(errorsMap);

        ModelAndView modelAndView = new ModelAndView("fail");
        modelAndView.addObject("errorInfo", errorsMap);

        return modelAndView;
    }

    @ExceptionHandler(NoSuchAccountException.class)
    public ModelAndView loginFail() {
        ModelAndView modelAndView = new ModelAndView("fail");
        return modelAndView;
    }

}
